const DB_NAME = "FileUploadDB";
const STORE_NAME = "fileChunks";
const DB_VERSION = 1;

async function initDB() {
  return new Promise((resolve, reject) => {
    const request = indexedDB.open(DB_NAME, DB_VERSION);

    request.onupgradeneeded = (event) => {
      const db = event.target.result;
      if (!db.objectStoreNames.contains(STORE_NAME)) {
        const store = db.createObjectStore(STORE_NAME, {
          keyPath: "id",
          autoIncrement: true,
        });
        store.createIndex("fileId", "fileId", { unique: false });
        store.createIndex("status", "status", { unique: false });
      }
    };

    request.onsuccess = () => resolve(request.result);
    request.onerror = () => reject(request.error);
  });
}

export default class UploadManager {
  constructor() {
    this.dbPromise = initDB();
  }

  async #getStore(mode = "readwrite", operation) {
    const db = await this.dbPromise;
    return new Promise((resolve, reject) => {
      const tx = db.transaction(STORE_NAME, mode);
      const store = tx.objectStore(STORE_NAME);

      tx.oncomplete = () => resolve();
      tx.onerror = (e) => reject(e.target.error);

      try {
        const request = operation(store, tx);
        if (request?.onerror) {
          request.onerror = (e) => {
            console.error("操作失败:", e.target.error);
            resolve(); // 不reject以保证其他操作继续
          };
        }
      } catch (err) {
        reject(err);
      }
    });
  }

  // 添加分片记录
  async addChunks(fileId, chunks) {
    console.log(fileId, chunks, "====56");
    // 1. 在事务外准备数据
    const buffers = await Promise.all(
      chunks.map((chunk) => chunk.chunk.arrayBuffer())
    );
    console.log(buffers, "=====61");
    await this.#getStore("readwrite", async (store) => {
      buffers.forEach((buffer, index) => {
        const request = store.add({
          fileId,
          index,
          chunkData: buffer,
          status: "pending",
          size: chunks[index].size,
          type: chunks[index].type,
        });
        console.log(request, "===72");
        request.onerror = (e) =>
          console.error(`分片${index}存储失败:`, e.target.error);
      });
    });
  }

  // 更新分片状态
  async updateChunkStatus(fileId, index, status) {
    await this.#getStore("readwrite", async (store) => {
      const chunks = await new Promise((resolve) => {
        const request = store.index("fileId").getAll(IDBKeyRange.only(fileId));
        request.onsuccess = () => resolve(request.result);
      });

      const chunk = chunks.find((c) => c.index === index);
      if (chunk) {
        await new Promise((resolve) => {
          chunk.status = status;
          const request = store.put(chunk);
          request.onsuccess = () => resolve();
          request.onerror = (e) => {
            console.error("状态更新失败:", e.target.error);
            resolve();
          };
        });
      }
    });
  }

  // 获取待上传分片
  async getPendingChunks(fileId) {
    const db = await this.dbPromise;
    return new Promise((resolve) => {
      const tx = db.transaction(STORE_NAME, "readonly");
      const store = tx.objectStore(STORE_NAME);

      // 1. 合并两种状态的查询
      const pendingQuery = store
        .index("status")
        .getAll(IDBKeyRange.only("pending"));
      const uploadingQuery = store
        .index("status")
        .getAll(IDBKeyRange.only("uploading"));

      // 2. 统一处理结果
      const results = [];
      let completedCount = 0;

      const handleResult = (items) => {
        results.push(...items.filter((c) => c.fileId === fileId));
        if (++completedCount === 2) {
          // 3. 转换数据格式
          const chunks = results.map((item) => ({
            ...item,
            chunkData: new Blob([item.chunkData], {
              type: item.type || "application/octet-stream",
            }),
          }));
          resolve(chunks);
        }
      };

      pendingQuery.onsuccess = (e) => handleResult(e.target.result || []);
      uploadingQuery.onsuccess = (e) => handleResult(e.target.result || []);

      tx.onerror = () => resolve([]); // 出错返回空数组
    });
  }

  // 清理已完成记录
  async cleanCompleted(fileId) {
    await this.#getStore("readwrite", async (store) => {
      const chunks = await new Promise((resolve) => {
        const request = store.index("fileId").getAll(IDBKeyRange.only(fileId));
        request.onsuccess = () => resolve(request.result);
      });

      await Promise.all(
        chunks
          .filter((c) => c.status === "completed")
          .map(
            (c) =>
              new Promise((resolve) => {
                const request = store.delete(c.id);
                request.onsuccess = () => resolve();
                request.onerror = () => resolve(); // 忽略单个删除错误
              })
          )
      );
    });
  }

  async clearStore() {
    await this.#getStore("readwrite", async (store) => {
      console.log(store, "====167");
      return new Promise((resolve, reject) => {
        const request = store.clear();
        request.onsuccess = () => resolve();
        request.onerror = (err) => reject(err); // 忽略单个删除错误
      });
    });
  }
}
